#!/usr/bin/env python
# -*- coding:utf-8 -*-

start = 1  # 起始值
end = 100  # 结束值


class WeightLossPlanService:
    std_array = {}

    def __init__(self, conn):
        self.conn = conn

    def calculation_ingredient_ratio_with_dinner(self, dinners, dinnerStdWeight, vitaminProportion):
        _ary_key = ["zaocan", "wucan", "wancan"]
        _ary_mem_weight_name = ["proteinWeight", "carbonWaterWeight", "fatWeight", "vitaminWeight"]
        try:
            _tot = []
            view = []
            view2 = {}
            for one_dinner in dinners:
                _str_dinner = one_dinner["dinner"]
                _ary_col_intake_weight = [] # 每一餐，统计数据置空
                for _ary_mem_weight_name_idx in range(len(_ary_mem_weight_name)):
                    _one_dinner_ary = one_dinner[_str_dinner][_ary_mem_weight_name[_ary_mem_weight_name_idx]]
                    for _one_dinner_idx in range(len(_one_dinner_ary)):
                        # 食材与摄入热量的转化计算
                        food_cal = _one_dinner_ary[_one_dinner_idx]["food"]
                        check_cal_flg_data = self.load_one_food(food_cal)
                        # 维生素类食材特殊，不需要进行克重转换，直接使用标准克重-（热量计算克重）的剩余值
                        recal = True
                        if check_cal_flg_data is not None and check_cal_flg_data[5] == "1":
                            recal =False
                        items = self.load_food_data(food_cal, recal=recal)
                        _one_dinner_ary[_one_dinner_idx]["food"] = self.chg_fooddb_data(one_dinner=food_cal, foods=items)
                # 计算维生素食材的克重数量，从计算餐食数量，转换到整餐食数量空，依据餐食标准值，超过餐食则表现实际值，否则依据标准餐食-热量餐食 / 维生素餐食数量 核准计算。 4月8日调整
                arry_vim_foods = [i for i in one_dinner[_str_dinner]["proteinWeight"]]
                for vim_foods in arry_vim_foods:
                    vim_foods["intake"]= vim_foods["food"]["intake"]
                    _ary_col_intake_weight.append(vim_foods["food"]["intake"])
                arry_vim_foods = [i for i in one_dinner[_str_dinner]["carbonWaterWeight"]]
                for vim_foods in arry_vim_foods:
                    vim_foods["intake"] = vim_foods["food"]["intake"]
                    _ary_col_intake_weight.append(vim_foods["food"]["intake"])
                arry_vim_foods = [i for i in one_dinner[_str_dinner]["fatWeight"]]
                for vim_foods in arry_vim_foods:
                    vim_foods["intake"] = vim_foods["food"]["intake"]
                    _ary_col_intake_weight.append(vim_foods["food"]["intake"])
                cal_col_intake_tot_weight = sum(_ary_col_intake_weight)
                # 计算补差的维生素配菜
                diff_weight = 0
                if float(dinnerStdWeight) > cal_col_intake_tot_weight:
                    diff_weight = float(dinnerStdWeight) - cal_col_intake_tot_weight
                elif float(dinnerStdWeight) < cal_col_intake_tot_weight:
                    # 补充一定比值的维生素配餐
                    diff_weight = float(dinnerStdWeight) * (vitaminProportion / 100)
                # 代码改造补充，设定一个维生素类餐食的基准值，如果维生素总参量低于该值，则使用该值 2024-04-12
                vitaminDefaultWeight_val = int(self.load_default_vitm_val())
                if diff_weight < vitaminDefaultWeight_val:
                    diff_weight = vitaminDefaultWeight_val
                # 获取配餐维生素餐食
                arry_vim_foods = [i for i in one_dinner[_str_dinner]["vitaminWeight"]]
                for vim_foods in arry_vim_foods:
                    vim_foods["food"]["intake"] = round(diff_weight / len(arry_vim_foods), 0)
                    vim_foods["intake"] = vim_foods["food"]["intake"]
                # 开始处理界面展示的数据---------------------------------- START
                _view = []
                for key, value in one_dinner[_str_dinner].items():
                    for __inner_data_idx in range(len(value)):
                        _ddd = {"name": value[__inner_data_idx]["name"],
                                "intake": value[__inner_data_idx]["food"]["intake"],
                                "food": value[__inner_data_idx]["food"]["name"],
                                "unit": value[__inner_data_idx]["food"]["unit"]}
                        _ary_col_intake_weight.append(value[__inner_data_idx]["food"]["intake"])
                        _view.append(_ddd)
                    view2[_str_dinner] = _view
                # 开始处理界面展示的数据---------------------------------- END
                # 汇总计算
                for key, value in one_dinner[_str_dinner].items():
                    for __inner_data_idx in range(len(value)):
                        _tot.append({"name": value[__inner_data_idx]["food"]["name"],
                                     "intake": value[__inner_data_idx]["food"]["intake"]})
                view.append({_str_dinner: _view})
            return {"code": 200, "data": {"ARRY": view, "DICT": view2, "TOT": _tot}}
        except Exception as e:
            print(e)
        return {"code": 500, "data": None}

    def calculation_ingredient_groups(self):
        try:
            fetch_sql = f" SELECT `classification`,`explain` FROM `mem_food_catalogs` WHERE 1=1 GROUP BY `classification`"
            items = self.conn.sql_fetch(fetch_sql)
            if len(items) > 0:
                return {"code": 200, "data": items}
        except Exception as e:
            print(e)
        return {"code": 500, "data": None}

    def calculation_ingredient_ratio(self, calorie, count, catalogs):
        try:
            res = []
            for catalogs_item_index in range(len(catalogs)):
                catalog_dict = catalogs[catalogs_item_index]
                fetch_count_sql = f" SELECT count(`id`) " \
                                  f" FROM mem_food_catalogs" \
                                  f" WHERE 1=1 AND `label_recognition` = \'{catalog_dict['key']}\'" \
                                  f" GROUP BY classification"
                catalogs_counts = self.conn.sql_fetch(fetch_count_sql)
                fetch_sql = f" SELECT `id`, `classification`, `label_recognition`" \
                            f" FROM mem_food_catalogs" \
                            f" WHERE 1=1 AND `label_recognition` = \'{catalog_dict['key']}\'" \
                            f" AND (`unit_content_index` > 20 or `unit_content_index` =1)" \
                            f" GROUP BY classification"

                items = self.conn.sql_fetch(fetch_sql)
                if len(items) > 0:
                    # start = 1  # 起始值
                    # end = 100  # 结束值
                    for item in items:
                        # random_int = random.randrange(start, end)
                        # combinationRatio = float(random_int) # 随机食材热量占有率
                        # single_catalog_ratio = round(float(calorie) * (combinationRatio / 100) * 1, 2)
                        one_dinner_calorie_val = round(float(catalog_dict['val']) / 3, 2)
                        one_dinner_catalogs_calorie_val = round(one_dinner_calorie_val / len(catalogs_counts), 2)
                        res.append({"id": item[0],
                                    "classification": item[1],
                                    "labelRecognition": item[2],
                                    "count": count,
                                    "standardUnit": 1,
                                    "oneCatalogsIntake": one_dinner_catalogs_calorie_val,
                                    "intake": one_dinner_catalogs_calorie_val,
                                    "oneDinnerIntake": one_dinner_calorie_val
                                    # "combinationRatio": round(combinationRatio, 2),
                                    # "totalDailyIntake": single_catalog_ratio,
                                    })
            return {"code": 200, "data": res}
        except Exception as e:
            print(e)
        return {"code": 500, "data": None}

    def calculation_dinner(self, params, dinner_times):
        view_list = []
        for dinnertimes_index in range(len(dinner_times)):
            combination_list = []
            res = self.calculation_combination(params)
            ary_combination = res['data']
            for combination in ary_combination:
                combination_list.append({
                    "id": combination["id"],
                    "labelRecognition": combination["labelRecognition"],
                    "classification": combination["classification"],
                    "classification_weight": combination["classification_weight"],
                    "food_ingredients_name": combination["food_ingredients_name"],
                    "food_ingredients_weight": combination["food_ingredients_weight"],
                    "intake": combination["intake"],
                })
            view_list.append({"key": dinnertimes_index,
                              "dinner_label": dinner_times[dinnertimes_index],
                              "foods": combination_list})
        return {"code": 200, "data": view_list}

    def calculation_combination(self, params):
        ary_classifications = []
        # 根据count 和 class 随机选择数量，并匹配 单类食材 calorie 的克重
        for item in params:
            labelRecognition = item["labelRecognition"]
            classification = item["classification"]  # 食材分类
            # combinationRatio = item["combinationRatio"]  # 食材占比，取消人工配比食材，使用系统平均分配食材占比
            count = item["count"]  # 食材选择数量
            one_dinner_catalog_weight = round(item["intake"], 2)  # 单品种食材热量总值
            # 单一类别食材，匹配N个随机数。
            one_Classification = self.loadClassData(tags=classification, count=count, kgs=one_dinner_catalog_weight)
            if one_Classification['code'] == 200:
                ary_food_ingredients = one_Classification['data']
                for food_ingredients in ary_food_ingredients:
                    ary_classifications.append({
                        "id": food_ingredients["id"],
                        "labelRecognition": labelRecognition,
                        "classification": classification,
                        "classification_weight": one_dinner_catalog_weight,
                        "food_ingredients_name": food_ingredients["name"],
                        "food_ingredients_weight": round(one_dinner_catalog_weight / count, 2),
                        "intake": food_ingredients["unit_intake"],
                    })
        return {"code": 200, "data": ary_classifications}

    ##
    # 计算单人每一次算餐的热量食材分配，包含食材名称，单位热量，单食材总热量，需要配比克重
    ##
    def loadClassData(self, tags, count, kgs):
        try:
            single_food_calories = round(kgs / count, 2)
            fetch_sql = f" SELECT `id`,`name`,`classification`,`calorie`, ({single_food_calories} * 100) / `unit_content_index` as kgs FROM mem_food_catalogs WHERE 1 = 1 " \
                        f" AND `classification` = \"{tags}\" ORDER BY RAND() LIMIT {count}"
            items = self.conn.sql_fetch(fetch_sql)
            if len(items) > 0:
                res = [{"id": item[0],
                        "name": item[1],
                        "classification": item[2],
                        "unit_calories": single_food_calories,  # item[3],
                        "unit_intake": round(item[4], 2)
                        } for item in items]
                # 多加工一次数据，根据单一分类的总量，分别计算每个食材的配比量
                # for item_index in range(len(res)):
                #     random_int = random.randrange(start, end)
                #     flt_occupancy = (random_int / 100)
                #     cal_numn = float(kgs) * float(flt_occupancy)
                #     res[item_index]["totalDailyIntake"] = round(cal_numn, 2)
                #     res[item_index]["combinationRatio"] = round(flt_occupancy, 2)
                #     res[item_index]["calories"] = round(res[item_index]["totalDailyIntake"] * cal_numn, 2)
                return {"code": 200, "data": res}
            return {"code": 400, "data": None}
        except Exception as e:
            print(e)
        return {"code": 500, "data": None}

    def load_one_food(self, food):
        fetch_sql = f" SELECT `id`,`name`,`classification`, `label_recognition`, `calorie`, `unit_content_index` " \
                    f" FROM mem_food_catalogs" \
                    f" WHERE 1 = 1 " \
                    f" AND `name` = \'{food['name']}\' "
        items = self.conn.sql_fetch(fetch_sql)
        if len(items)==0:
            print("没有找到食材元素: %s" % fetch_sql)
            return None
        return items[0]

    def load_food_data(self, food, recal):
        if recal:
            fetch_sql = f" SELECT `id`,`name`,`classification`, `label_recognition`, `calorie`, " \
                        f" ({food['single_food_weight']} * 100) / `unit_content_index` as kgs, " \
                        f" unit_content_index" \
                        f" FROM mem_food_catalogs" \
                        f" WHERE 1 = 1 " \
                        f" AND `classification` = \'{food['catalog']}\'" \
                        f" AND `name` = \'{food['name']}\' " \
                        f" ORDER BY unit_content_index DESC"
        else:
            fetch_sql = f" SELECT `id`,`name`,`classification`, `label_recognition`, `calorie`, " \
                        f" ({food['single_food_weight']}) / `unit_content_index` as kgs, " \
                        f" unit_content_index" \
                        f" FROM mem_food_catalogs" \
                        f" WHERE 1 = 1 " \
                        f" AND `classification` = \'{food['catalog']}\'" \
                        f" AND `name` = \'{food['name']}\' " \
                        f" ORDER BY unit_content_index DESC"
        items = self.conn.sql_fetch(fetch_sql)
        if len(items)==0:
            print("没有找到食材元素: %s" % fetch_sql)
        return items

    def chg_fooddb_data(self, one_dinner, foods):
        if len(foods) > 0:
            _food_obj = foods[0]
            if _food_obj[1] == "鱼油":
                _dashabi_intake = round(float(_food_obj[5]), 2)
                if 0 < _dashabi_intake and _dashabi_intake < 1:
                    _dashabi_intake = 1
            else:
                _dashabi_intake = round(float(_food_obj[5]), 0)
            one_dinner['intake'] = _dashabi_intake
            one_dinner['cal_weight'] = round(one_dinner["single_food_weight"], 0)
            _view_food = {
                "id": _food_obj[0],
                "name": _food_obj[1],
                "catalog": one_dinner["catalog"],
                "single_food_weight": one_dinner["single_food_weight"],
                "unit": round(float(_food_obj[6]), 0),
                "classification": _food_obj[2],
                "labelRecognition": _food_obj[3],
                "count": 1,
                "standardUnit": 1,
                "intake": _dashabi_intake
            }
            one_dinner = _view_food
        else:
            _view_food = {
                "id": 0,
                "name": "食材缺失",
                "catalog": one_dinner["catalog"],
                "single_food_weight": one_dinner["single_food_weight"],
                "unit": round(0, 0),
                "classification": "食材缺失",
                "labelRecognition": "食材缺失",
                "count": 1,
                "standardUnit": 1,
                "intake": 0
            }
            one_dinner = _view_food
        return one_dinner

    def load_default_vitm_val(self):
        fetch_sql = f" SELECT `id`,`key`,`key_eng`, `col`, `val` " \
                    f" FROM `sys_dict`" \
                    f" WHERE 1 = 1 " \
                    f" AND `key_eng` = \'vitaminDefaultWeight\'"
        items = self.conn.sql_fetch(fetch_sql)
        if len(items)>0:
            return int(items[0][4])